﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ConfApp.Infrastructure;
using ConfApp.Models;
using ConfApp.Services;
using ConfApp.Services.Podcasts;
using ConfApp.Services.Twitter;
using Microsoft.Phone.Reactive;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Interactivity.InteractionRequest;
using Notification = Microsoft.Practices.Prism.Interactivity.InteractionRequest.Notification;

namespace ConfApp.ViewModels
{
    public class PodcastListViewModel : ViewModel
    {
        private readonly IPodcastStore _podcastStore;
        private readonly IPodcastUpdateService _podcastUpdateService;
        private readonly InteractionRequest<Notification> _submitErrorInteractionRequest;
        private readonly InteractionRequest<Notification> _submitNotificationInteractionRequest;

        private bool _isSyncing;


        private ObservableCollection<PodcastInfoViewModel> _observablePodcastInfo;
        private CollectionViewSource _podcastInfoViewSource;

        public PodcastListViewModel(
            IPodcastStore podcastStore,
            IPodcastUpdateService podcastUpdateService
            ,
            INavigationService navigationService)
            : base(navigationService)
        {
            _podcastStore = podcastStore;
            _podcastUpdateService = podcastUpdateService;
            this._submitErrorInteractionRequest = new InteractionRequest<Notification>();
            this._submitNotificationInteractionRequest = new InteractionRequest<Notification>();
            this.UpdateListCommand = new DelegateCommand(this.UpdateList);
            Initialize();
        }

        public DelegateCommand UpdateListCommand { get; set; }

        public IInteractionRequest SubmitErrorInteractionRequest
        {
            get { return this._submitErrorInteractionRequest; }
        }

        public IInteractionRequest SubmitNotificationInteractionRequest
        {
            get { return this._submitNotificationInteractionRequest; }
        }

        private void Initialize()
        {
            _version = -1;
            Refresh();

            this.PodcastSelectedCommand = new DelegateCommand<PodcastInfoViewModel>(
                p =>
                {
                    NavigationService.Navigate(
                        new Uri("/Views/PodcastView.xaml?id=" + p.ID, UriKind.Relative));
                });

            this.IsBeingActivated();
        }

        public bool IsSyncing
        {
            get { return this._isSyncing; }
            set
            {
                this._isSyncing = value;
                this.RaisePropertyChanged(() => this.IsSyncing);
            }
        }

        public void UpdateList()
        {
            if (this.IsSyncing)
            {
                return;
            }

            this.IsSyncing = true;
            this._podcastUpdateService
                .StartUpdating()
                .ObserveOnDispatcher()
                .Subscribe(taskSummarie => this.UpdatePodcastListCompleted(
                    new List<TaskCompletedSummary>
                        {
                            taskSummarie
                        }));
        }

        private void UpdatePodcastListCompleted(IEnumerable<TaskCompletedSummary> taskSummaries)
        {
            var stringBuilder = new StringBuilder();

            var errorSummary =
                taskSummaries.FirstOrDefault(
                    s =>
                        s.Result == TaskSummaryResult.UnreachableServer ||
                        s.Result == TaskSummaryResult.AccessDenied);

            if (errorSummary != null)
            {
                stringBuilder.AppendLine(GetDescriptionForSummary(errorSummary));
                this._submitErrorInteractionRequest.Raise(
                        new Notification { Title = "Greška pri učitavanju", Content = stringBuilder.ToString() },
                        n => { });
            }
            else
            {
                foreach (var task in taskSummaries)
                {
                    stringBuilder.AppendLine(GetDescriptionForSummary(task));
                }

                if (taskSummaries.Any(t => t.Result != TaskSummaryResult.Success))
                {
                    this._submitErrorInteractionRequest.Raise(
                        new Notification { Title = "Greška pri učitavanju", Content = stringBuilder.ToString() },
                        n => { });
                }
                else
                {
                    this._submitNotificationInteractionRequest.Raise(
                        new Notification { Title = stringBuilder.ToString(), Content = null },
                        n => { });
                }
            }

            // Update the View Model status

            Refresh();
            this.RaisePropertyChanged(string.Empty);
            this.IsSyncing = false;
            this.UpdateListCommand.RaiseCanExecuteChanged();
            ////this.UpdateCommandsForSync();
        }

        private static string GetDescriptionForSummary(TaskCompletedSummary summary)
        {
            switch (summary.Result)
            {
                case TaskSummaryResult.Success:
                    switch (summary.Task)
                    {
                        case PodcastUpdateService.UpdatingTask:
                            return string.Format(
                                CultureInfo.InvariantCulture,
                                summary.Context == "0" ? "nema novih podcast-a" : "novih podcast-a ({0})",
                                summary.Context);
                        default:
                            return string.Format(
                                CultureInfo.InvariantCulture,
                                "{0}: {1}",
                                summary.Task,
                                TaskCompletedSummaryStrings.GetDescriptionForResult(summary.Result));
                    }
                default:
                    return TaskCompletedSummaryStrings.GetDescriptionForResult(summary.Result);
            }
        }


        private int _version;
        private void Refresh()
        {
            var version = _podcastStore.Version;
            //if (version > _version)
            //{
                _version = version;
                _observablePodcastInfo = new ObservableCollection<PodcastInfoViewModel>();

                _podcastInfoViewSource = new CollectionViewSource {Source = _observablePodcastInfo};
                foreach (var podcast in _podcastStore.GetPodcasts())
                {
                    _observablePodcastInfo.Add(new PodcastInfoViewModel(podcast,NavigationService));
                }
            //}
        }



        public ICollectionView PodcastInfos
        {
            get
            {
                Refresh();
                return _podcastInfoViewSource.View;
            }
        }

        public DelegateCommand<PodcastInfoViewModel> PodcastSelectedCommand { get; set; }


        public override void IsBeingActivated()
        {

        }
    }
}
